#pragma once
#include <map>
#include <fstream>
#include <iostream>
#include <string>
#include <queue>
#include <clocale>

using namespace std;

namespace U33
{
	struct data
	{
		string word;
		int n;
		data()
		{
			word = "";
			n = 0;
		}

		friend bool operator< (const data &d1, const data &d2)
		{
			return d1.n < d2.n;
		}
	};

	class CalcWords
	{
	private:
		map<string, int> words;
		priority_queue<data> pqWords;

	public:

		CalcWords()
		{
		}

		~CalcWords()
		{
		}

		void ReadFromFile()
		{
			ifstream fin;
			fin.open("nils_holgersson.txt");
			string s;
			while (fin.good())
			{
				fin >> s;
				for (auto &w : words)
				{
					if (!w.first.compare(s))
					{
						w.second++;
					}
				}
				words.insert(std::pair<string, int>(s, 1));
			}
		}

		int FindMostFrequentWord(string &word)
		{
			int max = 0;
			for (auto &w : words)
			{
				if (w.second > max)
				{
					max = w.second;
					word = w.first;
				}
			}
			return max;
		}

		void AddWordsToQueue()
		{
			for (auto w : words)
			{
				data d;
				d.n = w.second;
				d.word = w.first;
				pqWords.push(d);
			}
		}

		data TopWord()
		{
			data d1;
			d1 = pqWords.top();
			pqWords.pop();
			return d1;
		}

		void mainU33()
		{
			setlocale(LC_ALL, "swedish");
			cout << ">>>>> Uppgift 3.3 <<<<<" << endl;
			cout << "Reading file... Please wait." << endl;
			ReadFromFile();
			cout << "Done reading file." << endl;
			string word;
			int amount;
			amount = FindMostFrequentWord(word);
			cout << "The word " << word << " appears " << amount << " times in the file." << endl << endl;
			AddWordsToQueue();
			for (int i = 1; i < 21; i++)
			{
				data d1;
				d1 = TopWord();
				cout << i << ". " << d1.word << " appears " << d1.n << " times in the text." << endl << endl;
			}
		}

	};
}

